/*
 * ring buffer example (keep one slot open)
 */
#include <stdio.h>
#include <string.h>


#define RING_SIZE 8
#define WRAP(a) (((a) == RING_SIZE) ? 0 : (a))


typedef struct {
    char buf[RING_SIZE];
    int iput;
    int iget;
} ring_t;

void ring_init (ring_t *ring)
{
    memset(ring->buf, '*', sizeof(ring->buf));
    ring->iput = 0;
    ring->iget = 0;
}
        
int ring_is_full (ring_t *ring)
{
    return ( ((ring->iput + 1) % RING_SIZE) == ring->iget);
}

int ring_is_empty (ring_t *ring)
{
    return (ring->iput == ring->iget);
}


int ring_put (ring_t *ring, char a)
{
    if (ring_is_full(ring)) {
        printf("put %c fail\n", a);
        return 0;
    }
    
    ring->buf[ring->iput] = a;
    ring->iput++;
    ring->iput %= RING_SIZE;
    
    return 1;
}

int ring_get (ring_t *ring, char *a)
{
    if (ring_is_empty(ring)) {
        printf("get fail\n");
        return 0;
    }
    
    *a = ring->buf[ring->iget];
    ring->buf[ring->iget] = '*';
    ring->iget++;
    ring->iget %= RING_SIZE;
    
    return 1;
}

void ring_dump (ring_t *ring)
{
    int i;

    for (i=0; i < RING_SIZE; i++) {
        printf("%c ", ring->buf[i]);
    }

    printf("\nsize=%d, iget=%d, iput=%d\n",
           (ring->iput + RING_SIZE - ring->iget) % RING_SIZE,
           ring->iget, ring->iput);
}

int main(int argc, char *argv[])
{
    ring_t ring;
    char a;

    ring_init(&ring);
    ring_dump(&ring);
    ring_get(&ring, &a);
    ring_put(&ring, 'a');
    ring_put(&ring, 'b');
    ring_put(&ring, 'c');
    ring_put(&ring, 'd');
    ring_put(&ring, 'e');
    ring_put(&ring, 'f');
    ring_put(&ring, 'g');
    ring_put(&ring, 'h');
    ring_put(&ring, 'i');
    ring_put(&ring, 'j');

    ring_get(&ring, &a);
    ring_get(&ring, &a);
    ring_get(&ring, &a);
    ring_put(&ring, 'k');
    ring_put(&ring, 'l');
    ring_put(&ring, 'm');
    ring_put(&ring, 'n');
    
    ring_dump(&ring);
    
    return 0;
}

    

    


